package gaboli.common.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * <strong>THE</strong> Object Instantiation Factory!
 *
 * @author C. Burrell (deltafront@gmail.com)
 */
public final class FactoryUtils
{
    private static Map<String, Object> objects;
    private static FactoryUtils factoryUtils;

    static
    {
        if( objects == null )
        {
            objects = new HashMap<String, Object>();
        }
    }

    private FactoryUtils()
    {}

    /**
     * @return Singleton instance of FactoryUtils.
     * @since 1.0
     */
    public static FactoryUtils getFactoryUtils()
    {
        if( factoryUtils == null )
        {
            factoryUtils = new FactoryUtils();
        }
        return factoryUtils;
    }


    /**
     * Returns an object that is of the type specified by the class name, or null
     * if that class cannot be loaded.
     *
     * @param class_name FQDN of class to be instantiated.
     * @return object of type, or null.
     * @since 1.0
     */
    public Object loadObject( String class_name )
    {
        return loadObject( class_name, false );
    }

    /**
     * Returns an object that is of the type specified by the class name, or null
     * if that class cannot be loaded. If the static indicator is set to 'true', then this instance will either be
     * loaded from an internal map, or, if it isn't present, it will be loaded into the map for future retrieval
     *
     * @param class_name FQDN of class to be instantiated.
     * @param is_static True if only a single reference to this instance is to be maintained.
     * @return object of type, or null.
     * @since 1.0
     */
    public Object loadObject( String class_name, boolean is_static )
    {
        Object out = null;
        try
        {
            if( is_static )
            {
                out = objects.get( class_name );
            }
            if( out == null )
            {
                out = Class.forName( class_name ).newInstance();
                if( is_static )
                {
                    objects.put( class_name, out );
                }
            }
        }
        catch( Exception e )
        {
            e.printStackTrace( System.err );
        }
        return out;
    }
}